class JWTParser {
    static parse(token) {
        try {
            if (!token || typeof token !== 'string') {
                return { success: false, error: 'Please provide a valid JWT token' };
            }

            token = token.trim();
            
            // Check if token has the correct JWT format (3 parts separated by dots)
            const parts = token.split('.');
            if (parts.length !== 3) {
                return { success: false, error: 'Invalid JWT format. JWT must have 3 parts separated by dots.' };
            }

            const [headerB64, payloadB64, signature] = parts;

            // Decode header
            let header;
            try {
                const headerJson = this.base64UrlDecode(headerB64);
                header = JSON.parse(headerJson);
            } catch (error) {
                return { success: false, error: 'Invalid JWT header encoding' };
            }

            // Decode payload
            let payload;
            try {
                const payloadJson = this.base64UrlDecode(payloadB64);
                payload = JSON.parse(payloadJson);
            } catch (error) {
                return { success: false, error: 'Invalid JWT payload encoding' };
            }

            // Parse claims
            const claims = this.parseClaims(payload);

            return {
                success: true,
                data: {
                    header,
                    payload,
                    signature: signature,
                    claims,
                    isExpired: claims.isExpired,
                    timeUntilExpiry: claims.timeUntilExpiry
                }
            };
        } catch (error) {
            return { success: false, error: `Failed to parse JWT: ${error.message}` };
        }
    }

    static base64UrlDecode(str) {
        // Convert base64url to base64
        str = str.replace(/-/g, '+').replace(/_/g, '/');
        
        // Add padding if needed
        while (str.length % 4) {
            str += '=';
        }
        
        try {
            // Decode base64
            const decoded = atob(str);
            
            // Convert to UTF-8
            return decodeURIComponent(escape(decoded));
        } catch (error) {
            throw new Error('Invalid base64url encoding');
        }
    }

    static parseClaims(payload) {
        const claims = {
            isExpired: false,
            timeUntilExpiry: null,
            issued: null,
            expires: null,
            notBefore: null
        };

        const now = Math.floor(Date.now() / 1000);

        // Parse standard claims
        if (payload.exp) {
            claims.expires = new Date(payload.exp * 1000).toISOString();
            claims.isExpired = payload.exp < now;
            if (!claims.isExpired) {
                claims.timeUntilExpiry = payload.exp - now;
            }
        }

        if (payload.iat) {
            claims.issued = new Date(payload.iat * 1000).toISOString();
        }

        if (payload.nbf) {
            claims.notBefore = new Date(payload.nbf * 1000).toISOString();
        }

        return claims;
    }

    static formatTimeRemaining(seconds) {
        if (!seconds || seconds <= 0) return 'Expired';
        
        const days = Math.floor(seconds / 86400);
        const hours = Math.floor((seconds % 86400) / 3600);
        const minutes = Math.floor((seconds % 3600) / 60);
        const secs = seconds % 60;

        const parts = [];
        if (days > 0) parts.push(`${days}d`);
        if (hours > 0) parts.push(`${hours}h`);
        if (minutes > 0) parts.push(`${minutes}m`);
        if (secs > 0) parts.push(`${secs}s`);

        return parts.join(' ');
    }

    static getAlgorithmDescription(alg) {
        const algorithms = {
            'HS256': 'HMAC with SHA-256',
            'HS384': 'HMAC with SHA-384',
            'HS512': 'HMAC with SHA-512',
            'RS256': 'RSA with SHA-256',
            'RS384': 'RSA with SHA-384',
            'RS512': 'RSA with SHA-512',
            'ES256': 'ECDSA with SHA-256',
            'ES384': 'ECDSA with SHA-384',
            'ES512': 'ECDSA with SHA-512',
            'PS256': 'RSA-PSS with SHA-256',
            'PS384': 'RSA-PSS with SHA-384',
            'PS512': 'RSA-PSS with SHA-512',
            'none': 'No signature'
        };
        
        return algorithms[alg] || `Unknown algorithm: ${alg}`;
    }
}